/**
 * 
 */
package com.zufangbao.earth.web.controller.assets;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.entity.Result;
import com.demo2do.core.persistence.support.Filter;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.utils.StringUtils;
import com.demo2do.core.web.interceptor.InfoMessage;
import com.demo2do.core.web.interceptor.MenuSetting;
import com.demo2do.core.web.resolver.Page;
import com.demo2do.core.web.resolver.Secure;
import com.zufangbao.earth.entity.security.Principal;
import com.zufangbao.earth.service.PrincipalService;
import com.zufangbao.sun.entity.Channel;
import com.zufangbao.sun.entity.company.corp.App;
import com.zufangbao.sun.entity.company.corp.AppAccount;
import com.zufangbao.sun.entity.contract.Contract;
import com.zufangbao.sun.entity.contract.PaymentInstrument;
import com.zufangbao.sun.entity.customer.Customer;
import com.zufangbao.sun.entity.house.House;
import com.zufangbao.sun.entity.house.HouseType;
import com.zufangbao.sun.entity.icbc.business.ContractAccount;
import com.zufangbao.sun.entity.order.Order;
import com.zufangbao.sun.service.AppService;
import com.zufangbao.sun.service.ContractAccountService;
import com.zufangbao.sun.service.ContractService;
import com.zufangbao.sun.service.CustomerService;
import com.zufangbao.sun.service.HouseService;
import com.zufangbao.sun.service.LandlordService;
import com.zufangbao.sun.service.OrderService;


/**
 * @author Downpour
 */
@Controller
@RequestMapping("/contracts")
@MenuSetting("menu-data")
public class ContractController {
	
	@Autowired
	private ContractService contractService;
	@Autowired
	private CustomerService customerService;
	@Autowired
	private HouseService houseService;
	@Autowired
	private AppService appService;
	@Autowired
	private LandlordService landlordService;
	@Autowired
	private OrderService orderService;
	@Autowired
	private ContractAccountService contractAccountService;
	@Autowired
	private PrincipalService principalService;
	/**
	 * List app contracts
	 * 
	 * @return
	 */
	@RequestMapping("")
	@MenuSetting("submenu-assets-contract")
	public ModelAndView list(Page page) {
		
		List<Contract> contractList = contractService.list(Contract.class, page);
		List<App> appList = this.appService.loadAll(App.class);
		ModelAndView modelAndView = new ModelAndView("contract/contract-list");
		modelAndView.addObject("contractList", contractList);
		modelAndView.addObject("appList", appList);
		modelAndView.addObject("page", page);
		
		return modelAndView;
	}
	
	@RequestMapping("/{contractId}/detail")
	@MenuSetting("submenu-assets-contract")
	public ModelAndView detail(@PathVariable Long contractId) {
		
		Contract contract = contractService.load(Contract.class, contractId);
		List<Order> totalOrderList = new ArrayList<Order>();
		Order currentOrder = orderService.getCurrentOrderByContract(contract, new Date());

		ModelAndView modelAndView = new ModelAndView("contract/contract-detail");

		if(currentOrder != null){
			modelAndView.addObject("currentOrder", currentOrder);
		}
		
		List<Order> orderList = orderService.getOrderList(contract);
		if(orderList != null)
		totalOrderList.addAll(orderList);
		
		modelAndView.addObject("contract", contract);
		modelAndView.addObject("orderList", totalOrderList);
		
		return modelAndView;
		
	}
	
	@RequestMapping("/create")
	@MenuSetting("submenu-assets-contract")
	public ModelAndView create(){
		
		List<App> appList = appService.loadAll(App.class);
		
		ModelAndView modelAndView = new ModelAndView("assets/asset-create");
		
		modelAndView.addObject("appList", appList);
		modelAndView.addObject("isFactoring", false);
		
		return modelAndView;
		
	}
	

	/**
	 * 
	 * @return
	 */
	@RequestMapping("/search")
	public ModelAndView search() {

		ModelAndView modelAndView = new ModelAndView("contract/contract-search");

		return modelAndView;
	}

	/**
	 * 
	 * @return
	 */
	@RequestMapping(value = "/search", method = RequestMethod.GET)
	@MenuSetting("submenu-assets-contract")
	public ModelAndView onSearch(HttpServletRequest request,@Secure Principal principal,
							     @RequestParam(value = "contractNo", required = false) String contractNo,
							     @RequestParam(value = "customerName", required = false) String customerName,
							     @RequestParam(value = "app", required = false ) String app,
							     @RequestParam(value = "community", required = false ) String community,
							     @RequestParam(value = "address", required = false ) String address,
							     Page page) {

		ModelAndView modelAndView = new ModelAndView("contract/contract-list");
		List<App> appList = this.principalService.get_can_access_app_list(principal);
		Filter filter = getContractFilter(contractNo, customerName, community,
				address,principal,app);
		List<Contract> contractList = new ArrayList<Contract>();
		if(!filter.getParameters().isEmpty()){
			contractList = contractService.list(Contract.class, filter, page);
		}
		
		String queryString = request.getQueryString();
		Map<String, String> queries = StringUtils.parseQueryString(queryString);
		if(queries.containsKey("page")) {
			queries.remove("page");
		}
		modelAndView.addObject("app", app);
		modelAndView.addObject("community", community);
		modelAndView.addObject("address", address);
		modelAndView.addObject("appList", appList);
		modelAndView.addObject("contractList", contractList);
		modelAndView.addObject("queryString", StringUtils.toQueryString(queries));
		modelAndView.addObject("contractNo", contractNo);
		modelAndView.addObject("customerName", customerName);
		
		return modelAndView;
	}

	public Filter getContractFilter(String contractNo, String customerName,
			String community, String address,Principal principal,String app_id) {
		Filter filter = new Filter();
		if(is_where_condition(contractNo)){
			filter.addLike("contractNo", contractNo);
		}
		if(is_where_condition(customerName)){
			filter.addLike("customer.name", customerName);
		}
		if(is_where_condition(community)){
			filter.addLike("house.community", community);
		}
		if(is_where_condition(address)){
			filter.addLike("house.address", address);
		}
		if (principal.is_app_role()) {
			filter.addEquals("app.id", principal.getKeyId());
		} else if(is_where_condition(app_id)) {
			filter.addEquals("app.id", Long.valueOf(app_id));
		}
		return filter;
	}

	private boolean is_where_condition(String address) {
		return !StringUtils.isEmpty(address);
	}

	private Filter getContractAccountFilter(String payAcNo, String payerName) {
		Filter contract_account_filter = new Filter();
		if(is_where_condition(payAcNo)){
			contract_account_filter.addLike("PayAcNo", payAcNo);
		}
		if(is_where_condition(payerName)){
			contract_account_filter.addLike("payerName", payerName);
		}
		return contract_account_filter;
	}

	@RequestMapping(value="/add", method=RequestMethod.POST)
	public @ResponseBody String add(Customer customer, House house, Contract contract, @RequestParam("type") int houseType, @RequestParam("houseCity") String city,
									@RequestParam("houseProvince") String province, @RequestParam("begin") String beginDate, @RequestParam("end") String endDate
									, @RequestParam("instrument") int paymentInstrument, @RequestParam("appId") Long appId)
	{
		App app = appService.load(App.class, appId);
		AppAccount appAccount = appService.getAppAccount(app, Channel.MOBILE);
		
		Result result = new Result();
		
		try {
			
			customerService.save(customer.initial(app, appAccount));
			houseService.save(house.initial(app, HouseType.ordinalOf(houseType), city, province));
			contractService.save(contract.initialize(app, customer, house, PaymentInstrument.ordinalOf(paymentInstrument), beginDate, endDate));
			
		}catch(Exception e) {
			
			result.message("新增租约失败");
			System.out.println(e.getMessage());
			
		}
		
		result.success().data("url", "contracts/add-success");
		return JsonUtils.toJsonString(result);

	}
	
	@RequestMapping(value="/import-contract-excel",method=RequestMethod.POST)
	public @ResponseBody String createContractData(MultipartFile file,String app){
		if(null == file){
			return "请添加文件";
		}
		if(!is_where_condition(app)){
			return "请选择二房东";
		}
		try {
			InputStream input = file.getInputStream();
			this.contractService.batchImportContractViaExcel(input,app);
			input.close();
		} catch (IOException e) {
			e.printStackTrace();
			return "导入失败";
		}
		return "导入成功";
	}
	
	@RequestMapping(value="/add-success")
	@InfoMessage("info.contract.create.success")
	public String addSuccess() {
		
		return "redirect:/contracts";
	}
	
	@RequestMapping(value="/contractAccount-search")
	@MenuSetting("submenu-assets-contract")
	public ModelAndView onSearchByContractAccountColumn(HttpServletRequest request,@Secure Principal principal,
							     @RequestParam(value = "payAcNo", required = false) String payAcNo,
							     @RequestParam(value = "payerName", required = false ) String payerName,
							     Page page) {

		ModelAndView modelAndView = new ModelAndView("contract/contract-list");
	
		// create Filter first
		List<App> appList = this.principalService.get_can_access_app_list(principal);
		List<Contract> contractList = new ArrayList<Contract>();
		Filter contract_account_filter = getContractAccountFilter(payAcNo,
				payerName);
		if(!contract_account_filter.getParameters().isEmpty()){
			List<ContractAccount> contractAccountList = contractAccountService.list(ContractAccount.class, contract_account_filter, page);
			for(ContractAccount ca : contractAccountList){
				contractList.add(ca.getContract());
			}
		}
		// handle query string
		String queryString = request.getQueryString();
		Map<String, String> queries = StringUtils.parseQueryString(queryString);
		if(queries.containsKey("page")) {
			queries.remove("page");
		}
		modelAndView.addObject("appList", appList);
		modelAndView.addObject("contractList", contractList);
		modelAndView.addObject("queryString", StringUtils.toQueryString(queries));
		modelAndView.addObject("payAcNo", payAcNo);
		modelAndView.addObject("payerName", payerName);
		
		return modelAndView;
	}
	
}